home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 16 / AMIGAplus Sonderheft 16 (1998)(ICP)(DE)[!].iso / pd / anwendungen / xpk_source / libraries / nuke / nuke.a next >
Text File  |  1998-08-27  |  13KB  |  794 lines

  1. ; ==================================================================
  2. ;                      xpkNUKE assembler routines
  3. ; ==================================================================
  4.     INCLUDE    "exec/types.i"
  5.     XDEF    _AsmPack
  6.     XDEF    _AsmUnpack
  7.     XDEF    NoReadN
  8.  
  9. tmp    EQUR    D0
  10. two    EQUR    D1
  11. len    EQUR    D2
  12. off    EQUR    D3
  13. i    EQUR    D5
  14. look    EQUR    D6
  15. arg    EQUR    D7
  16.  
  17. lst    EQUR    A3
  18. buf    EQUR    A5
  19. nxt    EQUR    A6
  20.  
  21.     STRUCTURE NukeData,0
  22.     APTR    inbuf
  23.     APTR    outbuf
  24.     APTR    last
  25.     APTR    next
  26.     APTR    cwri
  27.     APTR    uwri
  28.     APTR    uend
  29.     APTR    delpos
  30.     UWORD    ulen
  31.     UWORD    clen
  32.     UWORD    ustop
  33.     UWORD    ustart
  34.     UWORD    ucount
  35.     UWORD    scanrange
  36.     UWORD    room1
  37.     UWORD    room2
  38.     UWORD    room4
  39.     UWORD    roomN
  40.     UWORD    data1
  41.     UWORD    data2
  42.     ULONG    data4
  43.     ULONG    dataN
  44.     APTR    dest1
  45.     APTR    dest2
  46.     APTR    dest4
  47.     APTR    destN
  48.     ULONG    dummy
  49.     APTR    contbuf
  50.     ULONG    flags
  51.     LABEL    nd_sizeof
  52.  
  53. starts:    dc.w    0,0,4,10
  54.  
  55. dists:    dc.w    $0010,$0040,$0100,$0200
  56.     dc.w    $0010,$0080,$0200,$0800,$2000,$4000
  57.     dc.w    $0020,$0080,$0200,$0800,$2000,$4000
  58.  
  59.     dc.w    4,6,8,9
  60.     dc.w    4,7,9,11,13,14
  61.     dc.w    5,7,9,11,13,14
  62.  
  63.     dc.w    0,1,2,3
  64.     dc.w    4,5,6,7,8,9
  65.     dc.w    10,11,12,13,14,15
  66.  
  67. modes    dc.w    4,6,8,9
  68.     dc.w    4,7,9,11,13,14
  69.     dc.w    5,7,9,11,13,14
  70.  
  71. adds    dc.w    $0000,$0010,$0050,$0150
  72.     dc.w    $0000,$0010,$0090,$0290,$0a90,$2a90
  73.     dc.w    $0000,$0020,$00a0,$02a0,$0aa0,$2aa0
  74.  
  75.     dc.w    c2-TwoBitLen,c2-TwoBitLen,c2-TwoBitLen,c2-TwoBitLen
  76.     dc.w    c3-TwoBitLen,c3-TwoBitLen,c3-TwoBitLen,c3-TwoBitLen
  77.     dc.w    c3-TwoBitLen,c3-TwoBitLen
  78.     dc.w    0,0,0,0,0,0
  79.  
  80. WRITE0:    MACRO
  81. 30$    SUBQ.W    #1,room1(A4)
  82.     BCC.B    90$
  83.  
  84.     move.l    dest1(a4),a0
  85.     move.w    data1(a4),(a0)
  86.     move.l    cwri(a4),dest1(a4)
  87.     addq.l    #2,cwri(a4)
  88.     move.w    #15,room1(a4)
  89.  
  90. 90$    asl.w    data1(a4)
  91.     ENDM
  92.  
  93. WRITE1:    MACRO
  94. 31$    subq.w    #1,room1(a4)
  95.     bcc.s    91$
  96.  
  97.     move.l    dest1(a4),a0
  98.     move.w    data1(a4),(a0)
  99.     move.l    cwri(a4),dest1(a4)
  100.     addq.l    #2,cwri(a4)
  101.     move.w    #15,room1(a4)
  102.  
  103. 91$    asl.w    data1(a4)
  104.     addq.w    #1,data1(a4)
  105.     ENDM
  106.  
  107.  
  108.  
  109. WRITE2:    MACRO
  110. 32$    subq.w    #2,room2(a4)
  111.     bcc.s    92$
  112.  
  113.     move.l    dest2(a4),a0
  114.     move.w    data2(a4),(a0)
  115.     move.l    cwri(a4),dest2(a4)
  116.     addq.l    #2,cwri(a4)
  117.     move.w    #14,room2(a4)
  118.  
  119. 92$    asl.w    data2(a4)
  120.     asl.w    data2(a4)
  121.     or.w    arg,data2(a4)
  122.     ENDM
  123.  
  124.  
  125.  
  126. WRITE4:    MACRO
  127. 34$    subq.w    #4,room4(a4)
  128.     bcc.s    94$
  129.  
  130.     move.l    dest4(a4),a0
  131.     move.l    data4(a4),(a0)
  132.     move.l    cwri(a4),dest4(a4)
  133.     addq.l    #4,cwri(a4)
  134.     move.w    #28,room4(a4)
  135.     clr.l    data4(a4)
  136.  
  137. 94$    move.l    data4(a4),tmp
  138.     or.w    arg,tmp
  139.     ror.l    #4,tmp
  140.     move.l    tmp,data4(a4)
  141.     ENDM
  142.  
  143.  
  144.  
  145. WRITEN:    MACRO            ; d0,arg,a0
  146. 38$    moveq    #0,d0
  147.     move.l    dataN(a4),d0
  148.     asl.l    arg,d0
  149.     or.l    off,d0
  150.  
  151.     sub.w    arg,roomN(a4)
  152.     bcc.s    99$
  153.  
  154.     move.w    roomN(a4),arg
  155.     neg.w    arg
  156.     ror.l    arg,d0
  157.     move.l    destN(a4),a0
  158.     move.w    d0,(a0)
  159.     move.l    cwri(a4),destN(a4)
  160.     addq.l    #2,cwri(a4)
  161.     rol.l    arg,d0
  162.     neg.w    arg
  163.     add.w    #16,arg
  164.     move.w    arg,roomN(a4)
  165.  
  166. 99$    move.l    d0,dataN(a4)
  167.     ENDM
  168.  
  169.  
  170.  
  171. UNCOMP:    MACRO
  172.     addq.w    #1,ucount(a4)
  173.     bne.s    9$
  174.     move.w    i,ustart(a4)    ; first uncompressed
  175. 9$
  176.     ENDM
  177.  
  178.  
  179.  
  180. WRUNCO:            ; d2=number, Cc,  -d0, -a0, -a1
  181. ;    movem.l    a0-a6/d0-d7,-(sp)    ; DEBUG
  182. ;    bsr    _stat2
  183. ;    movem.l    (sp)+,a0-a6/d0-d7
  184.  
  185.     WRITE0
  186.     move.w    #-1,ucount(a4)    ; reset ucount
  187.  
  188.     move.w    ustart(a4),d0    ; write bytes
  189.     lea    -1(buf,d0.w),a0
  190.     move.l    uwri(a4),a1
  191.     move.w    d7,d0
  192. ;;;    lsr.w    #1,d0
  193. ;;;    bcc.s    86$
  194. 85$    move.b    (a0)+,-(a1)
  195. ;;;86$    move.b    (a0)+,-(a1)
  196.     dbra    d0,85$
  197.     move.l    a1,uwri(a4)
  198.  
  199.     tst.w    d7
  200.     bne.s    long
  201.     WRITE1
  202.     bra    uexit    ; len OK
  203.  
  204. long    move.w    d7,d0
  205.     WRITE0
  206. loop    cmp.w    #3,d0
  207.     ble.s    last3
  208.     moveq    #0,d7
  209.     WRITE2
  210.     subq.w    #3,d0
  211.     bra.s    loop
  212.  
  213. last3    neg.w    d0
  214.     moveq    #3,d7
  215.     and.w    d0,d7
  216.     WRITE2
  217.  
  218. uexit    rts
  219.  
  220.  
  221.  
  222. _AsmPack:
  223.     movem.l    d2-d7/a2-a6,-(sp)
  224. ;    illegal        ; Debug
  225.     bsr    init
  226.  
  227.     moveq    #0,d0
  228.     moveq    #0,two
  229.     moveq    #0,d7
  230. ;================= Main loop
  231. mainloop:
  232. ;    movem.l    a0-a6/d0-d7,-(sp)    ; DEBUG
  233. ;    bsr    _stat3
  234. ;    movem.l    (sp)+,a0-a6/d0-d7
  235.  
  236.     moveq    #0,two
  237.     move.b    -1(buf,i.w),two
  238.     asl.w    #8,two
  239.     move.b    0(buf,i.w),two
  240.     add.l    two,two
  241.  
  242. ;================= Test compressable
  243.     move.w    0(lst,two.l),look
  244.     bne.s    byterunchk
  245.  
  246. ;================= Not compressable
  247. uncompressable
  248.     UNCOMP
  249.     move.w    i,0(lst,two.l)
  250.     addq.w    #1,i
  251.  
  252.     cmp.w    ustop(a4),i
  253.     blt.s    mainloop
  254.     bra    mainexit
  255.  
  256. ;================= Byterun
  257. byterunchk
  258.     move.b    -1(buf,i.w),d0
  259.     cmp.b    0(buf,i.w),d0
  260.     bne.s    getmatch
  261.  
  262.     lea    1(buf,i.w),a0
  263.     move.l    a0,a1
  264.  
  265.     move.w    ustop(a4),d4
  266.     sub.w    i,d4
  267. 1$    cmp.b    (a0)+,d0
  268.     dbne    d4,1$
  269.  
  270.  
  271.     move.l    a0,len
  272.     cmp.l    uend(a4),len
  273.     ble.s    3$
  274.     move.l    uend(a4),len
  275. 3$    sub.l    a1,len
  276.     cmp.w    #2,len
  277.     ble.s    getmatch ; ble
  278.  
  279.     moveq    #1,off
  280.     subq.w    #1,len
  281.  
  282.     UNCOMP
  283.     addq.w    #1,i
  284.     bra    gooddeal
  285.  
  286. ;================= Getmatch
  287. getmatch
  288.  
  289.     cmp.w    scanrange(a4),i    ; do we have to start deleting old entries?
  290.     bls.s    nodel
  291.  
  292.     moveq    #0,d7
  293.     move.w    i,d7
  294.     sub.w    scanrange(a4),d7
  295.     add.w    d7,d7
  296.     lea    0(nxt,d7.l),a1
  297.  
  298.     move.l    delpos(a4),a0
  299.     moveq    #0,d7
  300. 1$    move.l    d7,(a0)+    ; del two entries at once.
  301.     cmp.l    a0,a1
  302.     bcc.s    1$
  303.     move.l    a0,delpos(a4)
  304.  
  305. nodel
  306.     move.w    i,d4        ; lowlim = i-scanrange
  307.     sub.w    scanrange(a4),d4
  308.     bcc.s    1$
  309.     moveq    #0,d4
  310. 1$
  311.     lea    1(buf,i.w),a0    ; maxlenpos= buf+i+1
  312.     move.l    a0,d2
  313.     addq.l    #1,d2
  314.     move.l    a0,d0        ; cmpstart = buf+i+1
  315.     move.b    (a0),d7        ; testbyte = buf[i+1]
  316.  
  317.     move.l    buf,d3        ; foundpos = scanbuf+look
  318.     add.l    look,d3
  319.     addq.l    #2,d3
  320.  
  321.     move.l    buf,a2        ; testbase= buf
  322.     move.w    i,(nxt)        ; next[0]=i
  323.  
  324.     bra.s    ientry
  325.  
  326. ;================= Inner loop
  327. couldbemax:
  328.     lea    1(buf,look.w),a0    ; cmp1= scanbase+look
  329.     move.l    d0,a1        ; cmp2= scanstart
  330. 1$
  331.     cmpm.b    (a0)+,(a1)+    ; while(*cmp1++==*cmp2++)
  332.     beq.s    1$        ;   ;
  333.  
  334.     cmp.l    a1,d2        ; if( len>=maxlen )
  335.     bcc.s    NoNewMax
  336.  
  337. ;    tst.w    look
  338. ;    beq.s    FoundBestMatch
  339.  
  340.     cmp.w    d4,look        ;    if( look<=lowlim )
  341.     bls.s    FoundBestMatch    ;        goto QuitII
  342.  
  343.     sub.l    d2,a2        ;    testbase+= maxlen-len
  344.     add.l    a1,a2
  345.     move.l    a1,d2        ;    maxlenpos= len
  346.     move.l    a0,d3        ;    foundpos = cmp1
  347.     move.b    -(a1),d7    ;    testbyte = *(cmp2-1)
  348. NoNewMax:
  349.  
  350. ;================= Inner sanctum
  351. InnerInner:
  352.     add.w    look,look
  353.     move.w    0(nxt,look.l),look    ; look=Next[look]
  354. ientry    cmp.b    1(a2,look.w),d7
  355.     beq.s    1$
  356.  
  357.     add.w    look,look
  358.     move.w    0(nxt,look.l),look    ; look=Next[look]
  359.     cmp.b    1(a2,look.w),d7
  360.     bne.s    InnerInner
  361.  
  362. 1$    cmp.w    i,look
  363.     bne.s    couldbemax
  364.  
  365. ;================= Compute offs
  366.  
  367. FoundBestMatch:
  368.     sub.l    d2,off        ; offset = foundpos-maxlenpos
  369.     neg.l    off
  370.  
  371. ;    cmp.w    scanrange(a4),d0
  372. ;    ble.s    ok
  373. ;bug    nop
  374.  
  375. gotoffs    cmp.l    uend(a4),len
  376.     ble.s    nooverr
  377. overr    move.l    uend(a4),len
  378. nooverr    sub.l    d0,len        ; maxlen= maxlenpos-cmpstart
  379.     moveq    #0,d0
  380.  
  381.  
  382. ;================= Check if good deal
  383.     cmp.w    #1,len
  384.     bgt.s    gooddeal
  385.     cmp.w    #$150,off    ; FIXME!  (fixed CvR V1.03)
  386.     bcs.s    gooddeal
  387.  
  388.     moveq    #0,d7
  389.     move.w    i,d7
  390.     add.l    d7,d7
  391.     move.w    0(lst,two.l),0(nxt,d7.l)
  392.     bra    uncompressable
  393.  
  394. ;================= Compressable
  395. gooddeal
  396.     move.w    ucount(a4),d7    ; write uncompressed
  397.     blt.s    1$
  398.     jsr    WRUNCO
  399.     bra.s    hadunco
  400. 1$    WRITE1
  401.  
  402. hadunco
  403. ;    movem.l    a0-a6/d0-d7,-(sp)    ; DEBUG
  404. ;    bsr    _stat
  405. ;    movem.l    (sp)+,a0-a6/d0-d7
  406.  
  407.  
  408.     move.l    len,d0
  409.     cmp.w    #3,d0
  410.     ble.s    getmode
  411.     moveq    #3,d0
  412. ;================= Getmode
  413.  
  414. getmode    lea    starts(pc),a2
  415.     add.w    d0,d0
  416.     move.w    0(a2,d0.w),d0
  417.  
  418.     lea    dists(pc),a2
  419.     add.w    d0,d0
  420.     add.w    d0,a2
  421.  
  422. 2$    cmp.w    (a2),off
  423.     blt.s    wrmode
  424. 3$    sub.w    (a2)+,off
  425.     cmp.w    (a2),off
  426.     bge.s    3$
  427.  
  428. wrmode    move.w    64(a2),d7
  429.     WRITE4
  430.  
  431. wroffs    move.w    32(a2),d7
  432.     WRITEN
  433.  
  434.     cmp.w    #2,len
  435.     ble    genentries
  436.  
  437. ;================= Write len
  438. wrlen    move.l    len,d0
  439.     cmp.w    #5,d0
  440.     bgt.s    longlen
  441.  
  442.     subq.w    #3,d0
  443.     not.w    d0
  444.     moveq    #3,d7
  445.     and.w    d0,d7
  446.     WRITE2
  447.     bra    genentries
  448.  
  449. longlen    moveq    #0,d7
  450.     WRITE2
  451.     subq.w    #6,d0
  452. 1$    cmp.w    #14,d0
  453.     ble.s    last15
  454.     moveq    #0,d7
  455.     move.l    d0,-(sp)
  456.     WRITE4
  457.     move.l    (sp)+,d0
  458.     sub.w    #15,d0
  459.     bra.s    1$
  460.  
  461. last15    not.w    d0
  462.     moveq    #15,d7
  463.     and.w    d0,d7
  464.     WRITE4
  465.  
  466. ;================= Gen entries
  467. genentries
  468.     lea    1(buf,i.w),a0
  469.     move.w    i,d7
  470.     add.w    d7,d7
  471.     lsr.l    #1,two
  472.  
  473. ;    cmp.w    #1,off    ;
  474. ;    bne.s    entry    ;
  475.  
  476. ;    add.w    len,i    ;
  477. ;    addq.w    #1,i    ;
  478. ;    bra.s    mainchk    ;
  479.  
  480.     bra.s    entry
  481.  
  482. eloop    lsl.w    #8,two
  483.     move.b    (a0)+,two
  484. entry    lea    0(lst,two.l),a1
  485.     add.l    two,a1
  486.     move.w    (a1),0(nxt,d7.l)
  487.     move.w    i,(a1)
  488.     addq.w    #2,d7
  489.     addq.w    #1,i
  490.     dbra    len,eloop
  491.  
  492. ;================= End
  493. mainchk
  494. ;;;    add.l    two,two    ; not needed, since mainloop does recalculate it
  495.     cmp.w    ustop(a4),i
  496.     blt    mainloop
  497. mainexit
  498.     bsr    flush
  499.     bsr    compact
  500.  
  501.     movem.l    (sp)+,d2-d7/a2-a6
  502.     rts
  503.  
  504. ;======================================================================
  505. init    moveq    #0,d0
  506.     move.w    d0,room1(a4)
  507.     move.w    d0,room2(a4)
  508.     move.w    d0,room4(a4)
  509.     move.w    d0,roomN(a4)
  510.  
  511.     move.w    d0,data1(a4)
  512.     move.w    d0,data2(a4)
  513.     move.l    d0,data4(a4)
  514.     move.l    d0,dataN(a4)
  515.  
  516.     lea    dummy(a4),a0
  517.     move.l    a0,dest1(a4)
  518.     move.l    a0,dest2(a4)
  519.     move.l    a0,dest4(a4)
  520.     move.l    a0,destN(a4)
  521.  
  522.     move.l    last(a4),lst
  523.     move.l    inbuf(a4),buf
  524.     move.l    next(a4),nxt
  525.  
  526.     move.l    nxt,delpos(a4)
  527.     move.w    #$6a90,scanrange(a4)    ; $6aa0
  528.     subq.w    #1,scanrange(a4)
  529.  
  530.     move.l    outbuf(a4),cwri(a4)
  531.     move.l    outbuf(a4),a0
  532.     add.w    clen(a4),a0
  533.     move.l    a0,uwri(a4)
  534.  
  535.     move.l    inbuf(a4),a0
  536.     add.w    ulen(a4),a0
  537.     move.l    a0,uend(a4)
  538.  
  539.     move.w    ulen(a4),ustop(a4)
  540.     subq.w    #1,ustop(a4)
  541.  
  542.     moveq    #1,i
  543.     moveq    #0,two
  544.     moveq    #0,look
  545.  
  546.     move.w    #-1,ucount(a4)
  547.     move.w    #0,ustart(a4)
  548.     rts
  549.  
  550. ;======================================================================
  551. flush
  552.     cmp.w    ulen(a4),i
  553.     beq.s    just1
  554.     UNCOMP
  555. just1    UNCOMP
  556.     move.w    ucount(a4),d7
  557.     bsr    WRUNCO
  558.  
  559.     move.l    dest1(a4),a0
  560.     move.w    data1(a4),d0
  561.     move.w    room1(a4),d1
  562.     lsl.w    d1,d0
  563.     move.w    d0,(a0)
  564.  
  565.     move.l    dest2(a4),a0
  566.     move.w    data2(a4),d0
  567.     move.w    room2(a4),d1
  568.     lsl.w    d1,d0
  569.     move.w    d0,(a0)
  570.  
  571.     move.l    dest4(a4),a0
  572.     move.l    data4(a4),d0
  573.     move.w    room4(a4),d1
  574.     lsr.l    d1,d0
  575.     move.l    d0,(a0)
  576.  
  577.     move.l    destN(a4),a0
  578.     move.w    dataN+2(a4),d0
  579.     move.w    roomN(a4),d1
  580.     lsl.w    d1,d0
  581.     move.w    d0,(a0)
  582.  
  583.     rts
  584.  
  585.  
  586. ;======================================================================
  587. compact    move.l    uwri(a4),d0
  588.     sub.l    cwri(a4),d0
  589.     bge.s    3$
  590.  
  591.     moveq    #-1,d0
  592.     bra.s    exitc
  593.  
  594. 3$    move.l    uwri(a4),a2
  595.     move.l    outbuf(a4),a0
  596.     add.w    clen(a4),a0
  597.     sub.l    uwri(a4),a0
  598.     move.l    a0,d2
  599.     move.l    cwri(a4),a1
  600.  
  601. 1$    move.l    a1,d0
  602.     add.l    d2,d0
  603.     moveq    #3,d1
  604.     and.l    d0,d1
  605.     beq.s    copy
  606.     move.b    #$FB,(a1)+
  607.     bra.s    1$
  608.  
  609. copylp    move.b    (a2)+,(a1)+
  610. copy    dbra    d2,copylp
  611.  
  612.     move.l    a1,d0
  613.     sub.l    outbuf(a4),d0
  614. exitc    rts
  615.  
  616. ; d0=cmpstart     a0=cmp1
  617. ; d1=twochars+    a1=cmp2
  618. ; d2=maxlenpos    a2=testbase
  619. ; d3=foundpos     a3=lst+
  620. ; d4=lowerlimit   a4=
  621. ; d5=i+           a5=buf+
  622. ; d6=look+        a6=nxt+
  623. ; d7=testbyte     a7=
  624.  
  625. ;***************************************************************************
  626.  
  627.  
  628. _AsmUnpack
  629.     movem.l    d2-d7/a3-a6,-(a7)
  630.     MOVEA.L    A1,A5            ; only because of Maxon A5 problem
  631.     moveq    #16,d0
  632.     move.l    d0,a3
  633.     lea    modes,a6
  634.     moveq    #0,d0
  635.     moveq    #0,d1
  636.     move.w    #$8000,d2
  637.     move.w    #$8000,d3
  638.     moveq    #0,d4
  639.     moveq    #0,d5
  640.     moveq    #0,d6
  641.     moveq    #0,d7
  642.     bsr    TestCompressed
  643.     move.l    a0,d0
  644.     movem.l    (a7)+,d2-d7/a3-a6
  645.     rts
  646.  
  647. ; d0 mode        a0 writepos
  648. ; d1 offslen/offset    a1 copysrc
  649. ; d2 1bit_data        a2 writeend
  650. ; d3 2bits_data        a3 16
  651.  
  652. ; d4 4bits_data        a4 byteread
  653. ; d5 4bits_in        a5 wordread
  654. ; d6 xbits_data        a6 table
  655. ; d7 -xbits_in        a7
  656.  
  657. Compressed:
  658.     dbra    d5,NoRead4        ; 70    Read 4 bits (mode)
  659.     moveq    #7,d5            ; 8
  660.     move.l    (a5)+,d4        ; |
  661.     add.l    d4,d4            ; |
  662. NoRead4:                ;
  663.     moveq    #30,d0            ; 70
  664.     and.w    d4,d0            ; |
  665.     roxr.l    #4,d4            ; |
  666.                     ; |
  667.     move.w    0(a6,d0.w),d1        ; |
  668.                     ; |
  669.     clr.w    d6            ; |
  670.     rol.l    d1,d6            ; |    Read n bits (offset)
  671.     add.w    d1,d7            ; |     ble jumps on N|(Z^V)
  672.     ble.s    NoReadN            ; |    the add does never set V
  673.     moveq    #0,d1            ; 35
  674.     move.w    (a5)+,d1        ; |
  675.     asl.l    d7,d1            ; |    
  676.     swap    d1            ; |
  677.     or.l    d1,d6            ; |
  678.     sub.w    a3,d7            ; |
  679. NoReadN:                ;
  680.     move.l    a0,a1            ; 70
  681.     add.w    32(a6,d0.w),d6        ; |
  682.     sub.w    d6,a1            ; |
  683.                     ; |
  684.     move.w    64(a6,d0.w),d0        ; |
  685.     jmp    TwoBitLen(pc,d0.w)
  686.  
  687. TwoBitLen:
  688.     move.b    (a1)+,(a0)+        ; 21
  689.     move.b    (a1)+,(a0)+        ; |
  690.     move.b    (a1)+,(a0)+        ; |
  691.                     ; |
  692.     moveq    #0,d0            ; |    Read 2 bits (clen1)
  693.     add.w    d3,d3            ; |
  694.     bne.s    NoRead2x        ; |
  695.     move.w    (a5)+,d3        ; 1
  696.     addx.w    d3,d3            ; |
  697. NoRead2x:                ;
  698.     addx.w    d0,d0            ; 9
  699.     add.w    d3,d3            ; |
  700.     addx.w    d0,d0            ; |
  701.  
  702.     add.w    d0,d0
  703.     jmp    CJTable(pc,d0.w)
  704. CJTable:
  705.     bra.s    Tab15
  706. c3:    move.b    (a1)+,(a0)+        ; 21
  707. c2:    move.b    (a1)+,(a0)+        ; 21
  708.     move.b    (a1)+,(a0)+        ; |
  709.  
  710. ;----------------------------------------
  711. TestCompressed:                ;
  712.     add.w    d2,d2            ; 70    Read 1 (cbit)
  713.     bcc.s    Uncompressed        ; |
  714.     bne.s    Compressed        ; |
  715.     move.w    (a5)+,d2        ; 4
  716.     addx.w    d2,d2            ; |
  717.     bcs.s    Compressed        ; 70
  718. ;----------------------------------------
  719.  
  720. Uncompressed:                ;
  721.     add.w    d2,d2            ; 30    Read 1 (ulen1)
  722.     bne.s    1$            ; |
  723.     move.w    (a5)+,d2        ; 2
  724.     addx.w    d2,d2            ; |
  725. 1$                    ;
  726.     bcc.s    Copy3Entry        ; 30
  727.     move.b    -(a4),(a0)+        ; 15
  728. TestExit:                ; |
  729.     cmp.l    a2,a0            ; |
  730.     blt    Compressed        ; |
  731.     rts
  732.  
  733. CopyThree:
  734.     move.b    -(a4),(a0)+        ; 9
  735.     move.b    -(a4),(a0)+        ; |
  736.     move.b    -(a4),(a0)+        ; |
  737. Copy3Entry:
  738.     moveq    #0,d0            ; 30    Read 2 (ulen2)
  739.     add.w    d3,d3            ; |
  740.     bne.s    NoRead2a        ; |
  741.     move.w    (a5)+,d3        ; 4
  742.     addx.w    d3,d3            ; |
  743. NoRead2a:                ;
  744.     addx.w    d0,d0            ; 30
  745.     add.w    d3,d3            ; |
  746.     addx.w    d0,d0            ; |
  747.     add.w    d0,d0            ; |
  748.     jmp    UJTable(pc,d0.w)    ; |
  749.  
  750. UJTable:
  751.     bra.s    CopyThree        ; 3
  752.     move.b    -(a4),(a0)+        ; 7
  753.     move.b    -(a4),(a0)+        ; 10
  754.     move.b    -(a4),(a0)+        ; 15
  755.     move.b    -(a4),(a0)+        ; 15
  756.     cmp.l    a2,a0            ; |
  757.     blt    Compressed        ; |
  758.     rts                ;
  759.  
  760. ;---------------------------------------
  761. FJTable:
  762.     moveq    #0,d0
  763.     move.b    (a1)+,(a0)+        ; |
  764.     move.b    (a1)+,(a0)+        ; |
  765.     move.b    (a1)+,(a0)+        ; |
  766.  
  767.     move.b    (a1)+,(a0)+        ; |
  768.     move.b    (a1)+,(a0)+        ; |
  769.     move.b    (a1)+,(a0)+        ; |
  770.     move.b    (a1)+,(a0)+        ; |
  771.  
  772.     move.b    (a1)+,(a0)+        ; |
  773.     move.b    (a1)+,(a0)+        ; |
  774.     move.b    (a1)+,(a0)+        ; |
  775.     move.b    (a1)+,(a0)+        ; |
  776.  
  777.     move.b    (a1)+,(a0)+        ; |
  778. Tab15    move.b    (a1)+,(a0)+        ; |
  779.     move.b    (a1)+,(a0)+        ; |
  780.     move.b    (a1)+,(a0)+        ; |
  781.     tst.b    d0
  782.     bne.s    TestCompressed
  783.  
  784.     dbra    d5,1$
  785.     moveq    #7,d5
  786.     move.l    (a5)+,d4
  787.     add.l    d4,d4
  788. 1$
  789.     moveq    #30,d0
  790.     and.w    d4,d0
  791.     roxr.l    #4,d4
  792.  
  793.     jmp    FJTable(pc,d0.w)
  794.